// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie;

import java.util.Stack;
import org.lwjgl.opengl.GL11;
import zombie.core.SpriteRenderer;
import zombie.core.math.Vector4;
import zombie.core.opengl.GLState;
import zombie.core.opengl.Shader;
import zombie.core.opengl.ShaderProgram;
import zombie.core.textures.Texture;
import zombie.iso.IsoCamera;
import zombie.iso.Vector2;
import zombie.iso.Vector3;
import zombie.util.Lambda;
import zombie.util.lambda.Invokers;

public final class IndieGL {
    public static int nCount = 0;
    private static final GLState.CIntValue tempInt = new GLState.CIntValue();
    private static final GLState.C2IntsValue temp2Ints = new GLState.C2IntsValue();
    private static final GLState.C3IntsValue temp3Ints = new GLState.C3IntsValue();
    private static final GLState.C4IntsValue temp4Ints = new GLState.C4IntsValue();
    private static final GLState.C4BooleansValue temp4Booleans = new GLState.C4BooleansValue();
    private static final GLState.CIntFloatValue tempIntFloat = new GLState.CIntFloatValue();
    private static final Stack<zombie.ShaderStackEntry> m_shaderStack = new Stack();

    public static void glBlendFunc(int a, int b) {
        if (SpriteRenderer.instance != null && SpriteRenderer.GL_BLENDFUNC_ENABLED) {
            GLState.BlendFuncSeparate.set(temp4Ints.set(a, b, a, b));
        }
    }

    public static void glBlendFuncSeparate(int a, int b, int c, int d) {
        if (SpriteRenderer.instance != null && SpriteRenderer.GL_BLENDFUNC_ENABLED) {
            GLState.BlendFuncSeparate.set(temp4Ints.set(a, b, c, d));
        }
    }

    public static void StartShader(Shader shader) {
        int _int = IsoCamera.frameState.playerIndex;
        StartShader(shader, _int);
    }

    public static void StartShader(Shader shader, int playerIndex) {
        if (shader != null) {
            StartShader(shader.getID(), playerIndex);
        } else {
            EndShader();
        }
    }

    public static void StartShader(int ID) {
        int _int = IsoCamera.frameState.playerIndex;
        StartShader(ID, _int);
    }

    public static void StartShader(int ID, int playerIndex) {
        SpriteRenderer.instance.StartShader(ID, playerIndex);
    }

    public static void EndShader() {
        SpriteRenderer.instance.EndShader();
    }

    public static void pushShader(Shader shader) {
        int _int = IsoCamera.frameState.playerIndex;
        m_shaderStack.push(zombie.ShaderStackEntry.alloc(shader, _int));
        StartShader(shader, _int);
    }

    public static void popShader(Shader shader) {
        if (m_shaderStack.isEmpty()) {
            throw new RuntimeException("Push/PopShader mismatch. Cannot pop. Stack is empty.");
        } else if (((zombie.ShaderStackEntry)m_shaderStack.peek()).getShader() != shader) {
            throw new RuntimeException("Push/PopShader mismatch. The popped shader != the pushed shader.");
        } else {
            zombie.ShaderStackEntry shaderStackEntry0 = (zombie.ShaderStackEntry)m_shaderStack.pop();
            shaderStackEntry0.release();
            if (m_shaderStack.isEmpty()) {
                EndShader();
            } else {
                zombie.ShaderStackEntry shaderStackEntry1 = (zombie.ShaderStackEntry)m_shaderStack.peek();
                StartShader(shaderStackEntry1.getShader(), shaderStackEntry1.getPlayerIndex());
            }
        }
    }

    public static void bindShader(Shader shader, Runnable invoke) {
        pushShader(shader);

        try {
            invoke.run();
        } finally {
            popShader(shader);
        }
    }

    public static <T1> void bindShader(Shader shader, T1 object, Invokers.Params1.ICallback<T1> iCallback) {
        Lambda.capture(
            shader, object, iCallback, (genericStack, shaderx, objectx, iCallbackx) -> bindShader(shaderx, genericStack.invoker(objectx, iCallbackx))
        );
    }

    public static <T1, T2> void bindShader(Shader shader, T1 object0, T2 object1, Invokers.Params2.ICallback<T1, T2> iCallback) {
        Lambda.capture(
            shader,
            object0,
            object1,
            iCallback,
            (genericStack, shaderx, object0x, object1x, iCallbackx) -> bindShader(shaderx, genericStack.invoker(object0x, object1x, iCallbackx))
        );
    }

    public static <T1, T2, T3> void bindShader(Shader shader, T1 object0, T2 object1, T3 object2, Invokers.Params3.ICallback<T1, T2, T3> iCallback) {
        Lambda.capture(
            shader,
            object0,
            object1,
            object2,
            iCallback,
            (genericStack, shaderx, object0x, object1x, object2x, iCallbackx) -> bindShader(
                    shaderx, genericStack.invoker(object0x, object1x, object2x, iCallbackx)
                )
        );
    }

    public static <T1, T2, T3, T4> void bindShader(
        Shader shader, T1 object0, T2 object1, T3 object2, T4 object3, Invokers.Params4.ICallback<T1, T2, T3, T4> iCallback
    ) {
        Lambda.capture(
            shader,
            object0,
            object1,
            object2,
            object3,
            iCallback,
            (genericStack, shaderx, object0x, object1x, object2x, object3x, iCallbackx) -> bindShader(
                    shaderx, genericStack.invoker(object0x, object1x, object2x, object3x, iCallbackx)
                )
        );
    }

    private static ShaderProgram.Uniform getShaderUniform(Shader shader, String string, int _int) {
        if (shader == null) {
            return null;
        } else {
            ShaderProgram shaderProgram = shader.getProgram();
            return shaderProgram == null ? null : shaderProgram.getUniform(string, _int, false);
        }
    }

    public static void shaderSetSamplerUnit(Shader shader, String loc, int textureUnit) {
        ShaderProgram.Uniform uniform = getShaderUniform(shader, loc, 35678);
        if (uniform != null) {
            uniform.sampler = textureUnit;
            ShaderUpdate1i(shader.getID(), uniform.loc, textureUnit);
        }
    }

    public static void shaderSetValue(Shader shader, String loc, float val) {
        ShaderProgram.Uniform uniform = getShaderUniform(shader, loc, 5126);
        if (uniform != null) {
            ShaderUpdate1f(shader.getID(), uniform.loc, val);
        }
    }

    public static void shaderSetValue(Shader shader, String loc, int val) {
        ShaderProgram.Uniform uniform = getShaderUniform(shader, loc, 5124);
        if (uniform != null) {
            ShaderUpdate1i(shader.getID(), uniform.loc, val);
        }
    }

    public static void shaderSetValue(Shader shader, String loc, Vector2 val) {
        shaderSetVector2(shader, loc, val.x, val.y);
    }

    public static void shaderSetValue(Shader shader, String loc, Vector3 val) {
        shaderSetVector3(shader, loc, val.x, val.y, val.z);
    }

    public static void shaderSetValue(Shader shader, String loc, Vector4 val) {
        shaderSetVector4(shader, loc, val.x, val.y, val.z, val.w);
    }

    public static void shaderSetVector2(Shader shader, String loc, float val_x, float val_y) {
        ShaderProgram.Uniform uniform = getShaderUniform(shader, loc, 35664);
        if (uniform != null) {
            ShaderUpdate2f(shader.getID(), uniform.loc, val_x, val_y);
        }
    }

    public static void shaderSetVector3(Shader shader, String loc, float val_x, float val_y, float val_z) {
        ShaderProgram.Uniform uniform = getShaderUniform(shader, loc, 35665);
        if (uniform != null) {
            ShaderUpdate3f(shader.getID(), uniform.loc, val_x, val_y, val_z);
        }
    }

    public static void shaderSetVector4(Shader shader, String loc, float val_x, float val_y, float val_z, float val_w) {
        ShaderProgram.Uniform uniform = getShaderUniform(shader, loc, 35666);
        if (uniform != null) {
            ShaderUpdate4f(shader.getID(), uniform.loc, val_x, val_y, val_z, val_w);
        }
    }

    public static void ShaderUpdate1i(int shaderID, int uniform, int uniformValue) {
        SpriteRenderer.instance.ShaderUpdate1i(shaderID, uniform, uniformValue);
    }

    public static void ShaderUpdate1f(int shaderID, int uniform, float uniformValue) {
        SpriteRenderer.instance.ShaderUpdate1f(shaderID, uniform, uniformValue);
    }

    public static void ShaderUpdate2f(int shaderID, int uniform, float value1, float value2) {
        SpriteRenderer.instance.ShaderUpdate2f(shaderID, uniform, value1, value2);
    }

    public static void ShaderUpdate3f(int shaderID, int uniform, float value1, float value2, float value3) {
        SpriteRenderer.instance.ShaderUpdate3f(shaderID, uniform, value1, value2, value3);
    }

    public static void ShaderUpdate4f(int shaderID, int uniform, float value1, float value2, float value3, float value4) {
        SpriteRenderer.instance.ShaderUpdate4f(shaderID, uniform, value1, value2, value3, value4);
    }

    public static void glBlendFuncA(int a, int b) {
        GL11.glBlendFunc(a, b);
    }

    public static void glEnable(int a) {
        SpriteRenderer.instance.glEnable(a);
    }

    public static void glDoStartFrame(int w, int h, float zoom, int player) {
        glDoStartFrame(w, h, zoom, player, false);
    }

    public static void glDoStartFrame(int w, int h, float zoom, int player, boolean isTextFrame) {
        SpriteRenderer.instance.glDoStartFrame(w, h, zoom, player, isTextFrame);
    }

    public static void glDoEndFrame() {
        SpriteRenderer.instance.glDoEndFrame();
    }

    public static void glColorMask(boolean bln, boolean bln1, boolean bln2, boolean bln3) {
        GLState.ColorMask.set(temp4Booleans.set(bln, bln1, bln2, bln3));
    }

    public static void glColorMaskA(boolean bln, boolean bln1, boolean bln2, boolean bln3) {
        GL11.glColorMask(bln, bln, bln3, bln3);
    }

    public static void glEnableA(int a) {
        GL11.glEnable(a);
    }

    public static void glAlphaFunc(int a, float b) {
        GLState.AlphaFunc.set(tempIntFloat.set(a, b));
    }

    public static void glAlphaFuncA(int a, float b) {
        GL11.glAlphaFunc(a, b);
    }

    public static void glStencilFunc(int a, int b, int c) {
        GLState.StencilFunc.set(temp3Ints.set(a, b, c));
    }

    public static void glStencilFuncA(int a, int b, int c) {
        GL11.glStencilFunc(a, b, c);
    }

    public static void glStencilOp(int a, int b, int c) {
        GLState.StencilOp.set(temp3Ints.set(a, b, c));
    }

    public static void glStencilOpA(int a, int b, int c) {
        GL11.glStencilOp(a, b, c);
    }

    public static void glTexParameteri(int a, int b, int c) {
        SpriteRenderer.instance.glTexParameteri(a, b, c);
    }

    public static void glTexParameteriActual(int glTexture2d, int glTextureMagFilter, int glLinear) {
        GL11.glTexParameteri(glTexture2d, glTextureMagFilter, glLinear);
    }

    public static void glStencilMask(int a) {
        GLState.StencilMask.set(tempInt.set(a));
    }

    public static void glStencilMaskA(int a) {
        GL11.glStencilMask(a);
    }

    public static void glDisable(int a) {
        SpriteRenderer.instance.glDisable(a);
    }

    public static void glClear(int a) {
        SpriteRenderer.instance.glClear(a);
    }

    public static void glClearA(int a) {
        GL11.glClear(a);
    }

    public static void glDisableA(int a) {
        GL11.glDisable(a);
    }

    public static void glLoadIdentity() {
        SpriteRenderer.instance.glLoadIdentity();
    }

    public static void glBind(Texture offscreenTexture) {
        SpriteRenderer.instance.glBind(offscreenTexture.getID());
    }

    public static void enableAlphaTest() {
        GLState.AlphaTest.set(GLState.CBooleanValue.TRUE);
    }

    public static void disableAlphaTest() {
        GLState.AlphaTest.set(GLState.CBooleanValue.FALSE);
    }

    public static void enableStencilTest() {
        GLState.StencilTest.set(GLState.CBooleanValue.TRUE);
    }

    public static void disableStencilTest() {
        GLState.StencilTest.set(GLState.CBooleanValue.FALSE);
    }

    public static boolean isMaxZoomLevel() {
        return SpriteRenderer.instance.isMaxZoomLevel();
    }

    public static boolean isMinZoomLevel() {
        return SpriteRenderer.instance.isMinZoomLevel();
    }
}
